/* Copyright © Worklight Ltd. 2006-2011.  All rights reserved. */

package com.worklight.androidgap.plugin;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.text.ClipboardManager;
import android.view.Display;
import android.view.WindowManager;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.widget.Toast;

import com.phonegap.api.PhonegapActivity;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import com.worklight.androidgap.WLAndroidUtils;
import com.worklight.androidgap.WLDroidGap;

public class Utils extends Plugin {
	private static final String MARKET_ANDROID_WEB_URL = "https://market.android.com/";
	private static final String MARKET_URL_PREFIX = "market://";
	// action constants
	private static final String ACTION_WRITE_PREF = "writePref";
	private static final String ACTION_READ_PREF = "readPref";
	private static final String ACTION_LOAD_SKIN = "loadSkin";
	private static final String ACTION_GET_SCREEN_HEIGHT = "getScreenHeight";
	private static final String ACTION_GET_SCREEN_WIDTH = "getScreenWidth";
	private static final String ACTION_OPEN_URL = "openURL";
	private static final String ACTION_GET_LOCALE = "getDeviceLocale";
	private static final String ACTION_CLEAR_SESSION_COOKIES = "clearSessionCookies";
	private static final String ACTION_COPY_TO_CLIPBOARD = "copyToClipboard";
	private static final String ACTION_TOAST = "toast";
	private static final String ACTION_CLEAR_HISTORY = "clearHistory";
	private static final String ACTION_GET_AVAILABLE_SPACE = "getAvailableSpace";
	// result action constants
	private static final String RESULT_HEIGHT = "height";
	private static final String RESULT_WIDTH = "width";	
	
	private Activity myactivity = null;
	
	public void openURL(String url) {
		Intent myIntent = null;
		try {
			if (url.indexOf(MARKET_URL_PREFIX) > -1){
				myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));   
			}else {
				URL urlParam = new URL(url);
				myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlParam.toExternalForm()));   
			}
			myactivity.startActivity(myIntent);
		} catch (MalformedURLException e){
			WLAndroidUtils.error("Failed to openURL '" + url + "'; Invalid URL format.");
		} catch (ActivityNotFoundException e) {
			if (url.indexOf(MARKET_URL_PREFIX) > -1){ 
				//probably start from emulator
				myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url.replace(MARKET_URL_PREFIX, MARKET_ANDROID_WEB_URL)));   
				myactivity.startActivity(myIntent);
			} else {
				WLAndroidUtils.error("Failed to openURL '" + url + "'; Invalid URL format.");
			}
		}
	}

	public int getScreenWidth() {
		Display display = ((WindowManager) myactivity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
		return display.getWidth(); 
	}

	public int getScreenHeight() {
		Display display = ((WindowManager) myactivity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
		return display.getHeight(); 
	}
	/**
	 * Loads a skin into the view.
	 * *** NOTE *** 
	 * When loading a skin the skinLoader.html is unloaded from the view and the main html is loaded.
	 * This process crashes the connection between phonegap js to the native CallbackServer.
	 * The error is displayed in the LogCat as:
	 * 
	 * INFO/Web Console(3574): JSCallback Error: Request failed...
	 * 
	 * The error doesnt cause any other problems.
	 * 
	 * @param skinId
	 * @param htmlFile
	 */
	public void loadSkin(String skinId, String htmlFile) {
		File skinDir = new File(((WLDroidGap)myactivity).getLocalStorageWebRoot() + "/" + skinId);
		if (!skinDir.exists()) {
			WLAndroidUtils.error("No skin defined for " + skinId + ", will load default skin.");
			skinId = "default";
			showWrongSkinDialog();
		}
		((WLDroidGap)myactivity).loadUrl(((WLDroidGap)myactivity).getWebUrl() + "/" + skinId + "/" + htmlFile);	
	}

	/**
	 * Special case for executin terminator dialog from native.
	 */
	private void showWrongSkinDialog() {  
		AlertDialog.Builder dlg = new AlertDialog.Builder(myactivity);
		dlg.setTitle("Device Unsupported");
		dlg.setMessage("The application is not supported on this device. You may face problems while using it.");
		dlg.setCancelable(false);
		dlg.setPositiveButton("OK", new AlertDialog.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		dlg.create();
		dlg.show();
	}

	@Override
	public PluginResult execute(String action, JSONArray args, String callbackId) {
		PluginResult.Status status = PluginResult.Status.OK;
		JSONObject result = new JSONObject();
		try {
			if (ACTION_OPEN_URL.equals(action)) {
				this.openURL(args.getString(0));
			} else if (ACTION_GET_SCREEN_WIDTH.equals(action)) {
				result.put(RESULT_WIDTH, this.getScreenWidth());	
			} else if (ACTION_GET_SCREEN_HEIGHT.equals(action)) {
				result.put(RESULT_HEIGHT, this.getScreenHeight());	
			} else if (ACTION_LOAD_SKIN.equals(action) && !myactivity.isFinishing()) {
				this.loadSkin(args.getString(0), args.getString(1));
			} else if (ACTION_READ_PREF.equals(action)) {
				return new PluginResult(status, WLAndroidUtils.readWLPref(myactivity, args.getString(0)));
			} else if (ACTION_WRITE_PREF.equals(action)) {
				WLAndroidUtils.writeWLPref(myactivity, args.getString(0), args.getString(1));
			} else if (ACTION_GET_LOCALE.equals(action)){
				return new PluginResult(status, Locale.getDefault().toString());
			} else if (ACTION_CLEAR_SESSION_COOKIES.equals(action)) {
				CookieSyncManager.createInstance(myactivity);
				CookieManager.getInstance().removeSessionCookie();
			} else if (ACTION_COPY_TO_CLIPBOARD.equals(action)) {
				ClipboardManager clipboardManager = (ClipboardManager) myactivity.getSystemService(Context.CLIPBOARD_SERVICE);
				clipboardManager.setText(args.getString(0));
				Toast toast = Toast.makeText(myactivity, "The text was sucessfully copied.", Toast.LENGTH_LONG);
				toast.show();
				WLAndroidUtils.debug("Copied text: " + args.getString(0));
			} else if (ACTION_TOAST.equals(action)) {
				Toast toast = Toast.makeText(myactivity, args.getString(0), Toast.LENGTH_LONG);
				toast.show();
			} else if (ACTION_CLEAR_HISTORY.equals(action)){				
				((WLDroidGap)myactivity).clearHistory();
			} else if (ACTION_GET_AVAILABLE_SPACE.equals(action)){
				return new PluginResult(status, getFreeSpaceOnDevice());
			}

			return new PluginResult(status, result);
		} 
		catch (JSONException e) {
			return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
		}
	}

	@Override
	public boolean isSynch(String arg0) {
		return true;
	}

	@Override
	public void setContext(PhonegapActivity activity) {
		myactivity = activity;		
	}
	
	/**
	 *  
	 * @return the amount of free space on the Android device in Bytes
	 */
	private long getFreeSpaceOnDevice() {
		File path = Environment.getDataDirectory();
		StatFs stat = new StatFs(path.getPath());
		long blockSize = stat.getBlockSize();
		long availableBlocks = stat.getAvailableBlocks();
		long availableStorageInBytes = blockSize * availableBlocks; 
		return availableStorageInBytes;
	}
}
